/*
 * @Author: 0x9DEFA478
 * @Date: 2021-03-11 17:53:34
 * @LastEditTime: 2021-05-07 23:45:32
 * @LastEditors: 0x9DEFA478
 * @Description: 自定义字符串操作
 * ============================================================================================================================================
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * ============================================================================================================================================
 * 
 */

#include "H_String.h"
#include <stdio.h>
#include <stdarg.h>


#ifndef NULL
#define NULL  ((void*)0)
#endif // !NULL


//                ===============examples===============
//       #define Size 1024
//       unsigned char Buffer[Size];
//       #define h_String(Format,...)  H_String(Buffer,Format,__VA_ARGS__)
//
//                ==================use=================
//
//       h_String("format",...);
//


//s S :字符串


typedef int (*String_Fun_Def)(char* wrPtr,char* sign,void* param);


static int String_Fun_E(char* wrPtr,char* sign,void* param);
static int String_Fun_F(char* wrPtr,char* sign,void* param);
static int String_Fun_I(char* wrPtr,char* sign,void* param);
static int String_Fun_X(char* wrPtr,char* sign,void* param);
static int String_Fun_x(char* wrPtr,char* sign,void* param);
static int String_Fun_S(char* wrPtr,char* sign,void* param);
static int String_Fun_123(char* wrPtr,char* sign,void* param);//AsciiCode 123 '{'



static const String_Fun_Def String_Funs[128]={



	

	[0]=NULL,//0
	[1]=NULL,//1
	[2]=NULL,//2
	[3]=NULL,//3
	[4]=NULL,//4
	[5]=NULL,//5
	[6]=NULL,//6
	[7]=NULL,//7
	[8]=NULL,//8
	[9]=NULL,//9

	[10]=NULL,//10
	[12]=NULL,//12
	[13]=NULL,//13
	[14]=NULL,//14
	[15]=NULL,//15
	[16]=NULL,//16
	[17]=NULL,//17
	[18]=NULL,//18
	[19]=NULL,//19

	[20]=NULL,//20
	[21]=NULL,//21
	[22]=NULL,//22
	[23]=NULL,//23
	[24]=NULL,//24
	[25]=NULL,//25
	[26]=NULL,//26
	[27]=NULL,//27
	[28]=NULL,//28
	[29]=NULL,//29

	[30]=NULL,//30
	[31]=NULL,//31
	[' ']=NULL,//32
	[33]=NULL,//33
	[34]=NULL,//34
	[35]=NULL,//35
	[36]=NULL,//36
	[37]=NULL,//37
	[38]=NULL,//38
	[39]=NULL,//39

	[40]=NULL,//40
	[41]=NULL,//41
	[42]=NULL,//42
	[43]=NULL,//43
	[44]=NULL,//44
	[45]=NULL,//45
	[46]=NULL,//46
	[47]=NULL,//47
	[48]=NULL,//48
	[49]=NULL,//49

	[50]=NULL,//50
	[51]=NULL,//51
	[52]=NULL,//52
	[53]=NULL,//53
	[54]=NULL,//54
	[55]=NULL,//55
	[56]=NULL,//56
	[57]=NULL,//57
	[58]=NULL,//58
	[59]=NULL,//59

	[60]=NULL,//60
	[61]=NULL,//61
	[62]=NULL,//62
	[63]=NULL,//63
	[64]=NULL,//64
	['A']=NULL,//65
	['B']=NULL,//66
	['C']=NULL,//67
	['D']=NULL,//68
	['E']=String_Fun_E,//69

	['F']=String_Fun_F,//70
	['G']=NULL,//71
	['H']=NULL,//72
	['I']=String_Fun_I,//73
	['J']=NULL,//74
	['K']=NULL,//75
	['L']=NULL,//76
	['M']=NULL,//77
	['N']=NULL,//78
	['O']=NULL,//79

	['P']=NULL,//80
	['Q']=NULL,//81
	['R']=NULL,//82
	['S']=String_Fun_S,
	['T']=NULL,//84
	['U']=NULL,//85
	['V']=NULL,//86
	['W']=NULL,//87
	['X']=String_Fun_X,//88
	['Y']=NULL,//89

	['Z']=NULL,//90
	[91]=NULL,//91
	[92]=NULL,//92
	[93]=NULL,//93
	[94]=NULL,//94
	[95]=NULL,//95
	[96]=NULL,//96
	['a']=NULL,//97
	['b']=NULL,//98
	['c']=NULL,//99

	['d']=NULL,//100
	['e']=String_Fun_E,//101
	['f']=String_Fun_F,//102
	['g']=NULL,//103
	['h']=NULL,//104
	['i']=String_Fun_I,//105
	['j']=NULL,//106
	['k']=NULL,//107
	['l']=NULL,//108
	['m']=NULL,//109

	['n']=NULL,//110
	['o']=NULL,//111
	['p']=NULL,//112
	['q']=NULL,//113
	['r']=NULL,//114
	['s']=String_Fun_S,//115
	['t']=NULL,//116
	['u']=NULL,//117
	['v']=NULL,//118
	['w']=NULL,//119

	['x']=String_Fun_x,//120
	['y']=NULL,//121
	['z']=NULL,//122
	['{']=String_Fun_123,//123
	[124]=NULL,//124
	[125]=NULL,//125
	[126]=NULL,//126
	[127]=NULL//127

};





//e E
static int String_Fun_E(char* wrPtr,char* sign,void* param){

	int rlen;

	char str[16];
	char* cp;
	double d;
	char e;

	e=sign[0];
	
	sign=&sign[1];

	str[0]='%';
	cp=&str[1];

	while((sign[0]!='\0')&&(sign[0]!='}'))
	{
		cp[0]=sign[0];
		sign=&sign[1];
		cp=&cp[1];
	}

	
	cp[0]=e;
	cp[1]='\0';

	d=*((double*)param);

	sprintf(wrPtr,str,d);

	rlen=0;

	while(wrPtr[0]!='\0')
	{
		rlen++;
		wrPtr=&wrPtr[1];
	}
	return rlen;
}

//f F
static int String_Fun_F(char* wrPtr,char* sign,void* param){
	
	int rlen;

	char str[16];
	char* cp;
	double d;

	sign=&sign[1];

	str[0]='%';
	cp=&str[1];

	while((sign[0]!='E')&&(sign[0]!='e')&&(sign[0]!='\0')&&(sign[0]!='}'))
	{
		cp[0]=sign[0];
		sign=&sign[1];
		cp=&cp[1];
	}

	if((sign[0]=='e')||(sign[0]=='E')){
		cp[0]=sign[0];
		cp=&cp[1];
	}
	else{
		cp[0]='l';
		cp[1]='f';
		cp=&cp[2];
	}
	cp[0]='\0';

	d=*((double*)param);

	sprintf(wrPtr,str,d);

	rlen=0;

	while(wrPtr[0]!='\0')
	{
		rlen++;
		wrPtr=&wrPtr[1];
	}
	return rlen;
}

//i I
static int String_Fun_I(char* wrPtr,char* sign,void* param){

	int rlen;

	int sVar_i;
	long long sVar_l;
	int minlen;
	char str[21];
	char* cp;

	if((sign[0]=='D')||(sign[0]=='d')){
		sign=&sign[2];

		sVar_l=*((long long*)param);
	}
	else{
		sign=&sign[1];

		sVar_i=*((int*)param);
		sVar_l=sVar_i;
	}


	minlen=0;
	while((sign[0]>='0')&&(sign[0]<='9')){
		minlen*=10;
		minlen+=sign[0]-'0';
		sign=&sign[1];
	}

	rlen=0;
	cp=str;

	//-9223372036854775808==0x8000000000000000
	if((unsigned long long)sVar_l==0x8000000000000000ULL){
	
		rlen=20;
		while(rlen<minlen){
			rlen++;
			wrPtr[0]=' ';
			wrPtr=&wrPtr[1];
		}

		wrPtr[19]		='8';
		wrPtr[18]		='0';
		wrPtr[17]		='8';
		wrPtr[16]		='5';
		wrPtr[15]		='7';
		wrPtr[14]		='7';
		wrPtr[13]		='4';
		wrPtr[12]		='5';
		wrPtr[11]		='8';
		wrPtr[10]		='6';
		wrPtr[9]		='3';
		wrPtr[8]		='0';
		wrPtr[7]		='2';
		wrPtr[6]		='7';
		wrPtr[5]		='3';
		wrPtr[4]		='3';
		wrPtr[3]		='2';
		wrPtr[2]		='2';
		wrPtr[1]		='9';
		wrPtr[0]		='-';

		return rlen;
	}
	else if(sVar_l==0){
		wrPtr[0]='0';
		return 1;
	}
	else{
		if(sVar_l<0)
		{
			sVar_l=-sVar_l;

			while(sVar_l!=0){
				rlen++;
				cp[0]=(sVar_l%10)+'0';
				cp=&cp[1];
				sVar_l/=10;
			}
			rlen++;
			cp[0]='-';
			cp=&cp[1];
			while(rlen<minlen){
				rlen++;
				cp[0]=' ';
				cp=&cp[1];
			}

			minlen=rlen;
			while(minlen>0)
			{
				minlen--;
				wrPtr[0]=str[minlen];
				wrPtr=&wrPtr[1];
			}

			return rlen;
		}
		else{

			while(sVar_l!=0){
				rlen++;
				cp[0]=(sVar_l%10)+'0';
				cp=&cp[1];
				sVar_l/=10;
			}
			while(rlen<minlen){
				rlen++;
				cp[0]=' ';
				cp=&cp[1];
			}

			minlen=rlen;
			while(minlen>0)
			{
				minlen--;
				wrPtr[0]=str[minlen];
				wrPtr=&wrPtr[1];
			}

			return rlen;
		}
	}
}

//X
static int String_Fun_X(char* wrPtr,char* sign,void* param){

	int rlen;
	int i;
	unsigned int val;
	unsigned int sVal_i;
	unsigned long long sVal_l;

	

	if((sign[0]=='D')||(sign[0]=='d')){

		sign=&sign[2];

		rlen=0;
		while((sign[0]>='0')&&(sign[0]<='9')){
			rlen*=10;
			rlen+=sign[0]-'0';
			sign=&sign[1];
		}

		i=rlen;
		sVal_l=*((unsigned long long*)param);
		while(i>0)
		{
			i--;
			val=(sVal_l>>(i*4))&0xF;

			if(val<10){
				wrPtr[0]='0'+val;
			}
			else{
				wrPtr[0]='A'-10+val;
			}
			wrPtr=&wrPtr[1];
		}
	}
	else{

		sign=&sign[1];

		rlen=0;
		while((sign[0]>='0')&&(sign[0]<='9')){
			rlen*=10;
			rlen+=sign[0]-'0';
			sign=&sign[1];
		}

		i=rlen;
		sVal_i=*((unsigned int*)param);
		while(i>0)
		{
			i--;
			val=(sVal_i>>(i*4))&0xF;

			if(val<10){
				wrPtr[0]='0'+val;
			}
			else{
				wrPtr[0]='A'-10+val;
			}
			wrPtr=&wrPtr[1];
		}
	}

	return rlen;
}

//x
static int String_Fun_x(char* wrPtr,char* sign,void* param){

	int rlen;
	int i;
	unsigned int val;
	unsigned int sVal_i;
	unsigned long long sVal_l;
	

	if((sign[0]=='D')||(sign[0]=='d')){

		sign=&sign[2];

		rlen=0;
		while((sign[0]>='0')&&(sign[0]<='9')){
			rlen*=10;
			rlen+=sign[0]-'0';
			sign=&sign[1];
		}

		i=rlen;
		sVal_l=*((unsigned long long*)param);
		while(i>0)
		{
			i--;
			val=(sVal_l>>(i*4))&0xF;

			if(val<10){
				wrPtr[0]='0'+val;
			}
			else{
				wrPtr[0]='a'-10+val;
			}
			wrPtr=&wrPtr[1];
		}
	}
	else{

		sign=&sign[1];

		rlen=0;
		while((sign[0]>='0')&&(sign[0]<='9')){
			rlen*=10;
			rlen+=sign[0]-'0';
			sign=&sign[1];
		}

		i=rlen;
		sVal_i=*((unsigned int*)param);
		while(i>0)
		{
			i--;
			val=(sVal_i>>(i*4))&0xF;

			if(val<10){
				wrPtr[0]='0'+val;
			}
			else{
				wrPtr[0]='a'-10+val;
			}
			wrPtr=&wrPtr[1];
		}
	}

	return rlen;
}

//s S
static int String_Fun_S(char* wrPtr,char* sign,void* param){

	int rlen;
	char* src_cp;

	rlen=0;
	src_cp=*((char**)param);

	while(src_cp[0]!='\0')
	{
		wrPtr[0]=src_cp[0];

		src_cp=&src_cp[1];
		wrPtr=&wrPtr[1];
		rlen++;
	}

	return rlen;
}

//{
static int String_Fun_123(char* wrPtr,char* sign,void* param){
	*wrPtr='{';
	return 1;
}

/**
 * @brief 格式化字符串
 * @param {unsigned char* Buf} 所使用的缓存
 * @param {char* Format} 格式 {...}代表参数 
 * {i} {I} 整型(int) {ixxx} {Ixxx} xxx为10进制数字 表示最短长度(xxx长度任意)
 * {X} {x} 16进制(unsigned int){xxxx} {Xxxx} xxx为10进制数字 表示最短长度(xxx长度任意) 
 * {Dxxx} {dxxx} {i},{I},{x},{X}的长整型模式
 * {f} {F} 浮点数(double) {Fyyy.xxx} {fyyy.xxx} {F.xxx} {f.xxx} yyy为10进制数字 为总字符最小长度 xxx为10进制数字 保留小数位数
 * {e} {E} 浮点数(double) 科学计数法 {eyyy.xxx} {Eyyy.xxx} yyy为10进制数字 为总字符最小长度 xxx为10进制数字 保留小数位数
 * {s} {S} 以'\0'结尾的字符串
 * @param {...} 参数
 * @return {char*} 生成的字符串
 */
char* H_String(unsigned char* Buf,char* Format,...){
	va_list argptr;

	unsigned long long paramLL;
	unsigned int paramL;
	double paramF;
	int rSize;
	char* fmt;
	char* sptr;
	int sSize;
	int FunResultSize;

	va_start(argptr, Format);

	fmt=Format;
	
	rSize=0;
	while(fmt[0]!='\0')
	{
		while((fmt[0]!='{')&&(fmt[0]!='\0'))
		{
			Buf[rSize]=fmt[0];
			fmt=&fmt[1];
			rSize++;
		}
		if(fmt[0]=='\0'){
			break;
		}
		else{
			fmt=&fmt[1];
		}

		sptr=fmt;
		sSize=0;
		while((fmt[0]!='}')&&(fmt[0]!='\0')){
			
			sSize++;
			fmt=&fmt[1];
		}
		if(sSize>0){

			if((sptr[0]=='D')||(sptr[0]=='d')){
				paramLL=va_arg(argptr,unsigned long long);
				if(sSize>1){
					if(String_Funs[(unsigned int)sptr[1]]!=NULL){
						FunResultSize=String_Funs[(unsigned int)sptr[1]]((char*)&Buf[rSize],sptr,&paramLL);
						rSize+=FunResultSize;
					}
				}
			}
			else if((sptr[0]=='e')||(sptr[0]=='f')||(sptr[0]=='E')||(sptr[0]=='F')){
				paramF=va_arg(argptr,double);
				if(String_Funs[(unsigned int)sptr[0]]!=NULL){
					FunResultSize=String_Funs[(unsigned int)sptr[0]]((char*)&Buf[rSize],sptr,&paramF);
					rSize+=FunResultSize;
				}
			}else if(sptr[0]=='{'){
				if(String_Funs[(unsigned int)sptr[0]]!=NULL){
					FunResultSize=String_Funs[(unsigned int)sptr[0]]((char*)&Buf[rSize],sptr,NULL);
					rSize+=FunResultSize;
				}
			}
			else{
				paramL=va_arg(argptr,unsigned int);
				if(String_Funs[(unsigned int)sptr[0]]!=NULL){
					FunResultSize=String_Funs[(unsigned int)sptr[0]]((char*)&Buf[rSize],sptr,&paramL);
					rSize+=FunResultSize;
				}
			}
		}
		if(fmt[0]=='\0'){
			break;
		}
		else{
			fmt=&fmt[1];
		}
	}

	Buf[rSize]='\0';

	va_end(argptr);
	return (char*)Buf;
}

/**
 * @brief 获取字符串长度
 * @param {char* string} 字符串
 * @return {int}字符串长度
 */
int H_StringGetLength(char* string){
	int rlen;

	rlen=0;
	while(string[0]!='\0'){
		rlen++;
		string=&string[1];
	}
	return rlen;
}

/**
 * @brief 复制字符串到数组
 * @param dst 要复制到的数组
 * @param string 字符串
 * @return 无
 */
void H_StringCopy(unsigned char* dst,char* string){
	while(string[0]!='\0'){
		dst[0]=string[0];
		dst=&dst[1];
		string=&string[1];
	}
	dst[0]='\0';
}



